home *** CD-ROM | disk | FTP | other *** search
/ Aminet 51 / Aminet 51 (2002)(GTI - Schatztruhe)[!][Oct 2002].iso / Aminet / dev / c / minigl.lha / MiniGL / src / vertexbuffer.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-07-03  |  22.3 KB  |  906 lines

  1. /*
  2.  * $Id: vertexbuffer.c,v 1.1.1.1 2000/04/07 19:44:51 hfrieden Exp $
  3.  *
  4.  * $Date: 2000/04/07 19:44:51 $
  5.  * $Revision: 1.1.1.1 $
  6.  *
  7.  * (C) 1999 by Hyperion
  8.  * All rights reserved
  9.  *
  10.  * This file is part of the MiniGL library project
  11.  * See the file Licence.txt for more details
  12.  *
  13.  */
  14.  
  15. /*
  16. Surgeon:
  17.  
  18. Changes to vertexbuffer building API:
  19. - added MGL_FLATSTRIP primitive similar to MGL_FLATFAN
  20. - reduced memory-reads/writes
  21. - implemented a normalbuffer instead of pr-vertex normals
  22. - texcoords are multiplied with width/height after culling.
  23. - moved color-clamp to the GLColor functions
  24. - glVertex only cares for vertex coords, colors and normal- index.
  25.  
  26. Most functions are now so small that the obvious step is to change parts of the API to macros/static inlines, since per-vertex funcs are called many thousands of times per frame.
  27. See include/mgl/mglmacros.h
  28.  
  29. - context->CurrentTexQ does not need to be cleared to 1.0 if only two texcoords are specified since it is only used if context->CurrentTexQValid is equal to GL_TRUE
  30. This boolean is only set in the event of glTexCoord4f and cleared to GL_FALSE by glBegin
  31. */
  32.  
  33. #include "sysinc.h"
  34. #include <stdio.h>
  35.  
  36. #if defined (__VBCC__) && defined(__M68K__)
  37.     #include <inline/timer_protos.h>
  38. #endif
  39.  
  40. static char rcsid[] = "$Id: vertexbuffer.c,v 1.1.1.1 2000/04/07 19:44:51 hfrieden Exp $";
  41.  
  42. #ifdef __VBCC__
  43. extern void d_DrawPoints        (GLcontext context);
  44. extern void d_DrawLines         (GLcontext context);
  45. extern void d_DrawLineStrip     (GLcontext context);
  46. extern void d_DrawTriangles     (GLcontext context);
  47. extern void d_DrawTrianglesVA   (GLcontext context);
  48. extern void d_DrawTriangleFan   (GLcontext context);
  49. extern void d_DrawTriangleStrip (GLcontext context);
  50. extern void d_DrawQuads         (GLcontext context);
  51. extern void d_DrawNormalPoly    (GLcontext context);
  52. extern void d_DrawSmoothPoly    (GLcontext context);
  53. extern void d_DrawMtexPoly      (GLcontext context);
  54. extern void d_DrawQuadStrip     (GLcontext context);
  55.    #if 0
  56. extern void d_DrawFlatFan       (GLcontext context);
  57. extern void d_DrawFlatStrip     (GLcontext context);
  58.    #else
  59. extern void d_DrawFlat          (GLcontext context);
  60.    #endif
  61.  
  62. #else
  63.  
  64. extern void d_DrawPoints        (struct GLcontext_t);
  65. extern void d_DrawLines         (struct GLcontext_t);
  66. extern void d_DrawLineStrip     (struct GLcontext_t);
  67. extern void d_DrawTriangles     (struct GLcontext_t);
  68. extern void d_DrawTriangleFan   (struct GLcontext_t);
  69. extern void d_DrawTriangleStrip (struct GLcontext_t);
  70. extern void d_DrawQuads         (struct GLcontext_t);
  71. extern void d_DrawNormalPoly    (struct GLcontext_t);
  72. extern void d_DrawSmoothPoly    (struct GLcontext_t);
  73. extern void d_DrawMtexPoly      (struct GLcontext_t);
  74. extern void d_DrawQuadStrip     (struct GLcontext_t);
  75. extern void d_DrawTrianglesVA   (struct GLcontext_t);
  76.    #if 0
  77. extern void d_DrawFlatFan        (struct GLcontext_t);
  78. extern void d_DrawFlatStrip      (struct GLcontext_t);
  79.    #else
  80.  extern void d_DrawFlat      (struct GLcontext_t);
  81.    #endif
  82. #endif
  83.  
  84. extern void tex_ConvertTexture  (GLcontext);
  85. extern void fog_Set             (GLcontext);
  86.  
  87.  
  88. #ifndef __VBCC__
  89.     #ifndef __PPC__
  90.     static struct Device *TimerBase;
  91.     #endif
  92. #else
  93.     #ifndef __PPC__
  94.     extern struct Device *TimerBase;
  95.     #endif
  96. #endif
  97.  
  98.  
  99. void TMA_Start(LockTimeHandle *handle);
  100. GLboolean TMA_Check(LockTimeHandle *handle);
  101.  
  102.  
  103. /*
  104. Timer based locking stuff.
  105.  
  106. TMA_Start starts the time measuring for the lock time. The 68k uses the ReadEClock
  107. function due to its low overhead. PPC will use GetSysTimePPC for the same reasons.
  108.  
  109. The EClock version reads the eclock and stores the current values in the handle.
  110. It then calculates a maximum lock time based on the assumption that the lock
  111. should be unlocked after 0.05 seconds (i.e. twenty times per second).
  112.  
  113. TMA_Check checks if the specified time has expired. If it returns GL_FALSE,
  114. the lock may be kept alive. On return of GL_TRUE, the lock must be released.
  115.  
  116. Note that this routine handles the case where the ev_hi values has changed, i.e.
  117. the eV_lo value had an overrun. This code also assumes, however, that the difference
  118. between the current and former ev_hi is no more than 1. This is, however, a very
  119. safe assumption; It takes approx. 100 minutes for the ev_hi field to increment,
  120. and it is extremely unlikely that the ev_hi field overruns - this will happen after
  121. approx. 820,000 years uptime (of course, a reliable system should be prepared for
  122. this)
  123.  
  124. */
  125.  
  126. #ifndef __PPC__
  127. void TMA_Start(LockTimeHandle *handle)
  128. {
  129.     struct EClockVal eval;
  130.     extern struct ExecBase *SysBase;
  131.     if (!TimerBase)
  132.     {
  133.         TimerBase = (struct Device *)FindName(&SysBase->DeviceList, "timer.device");
  134.     }
  135.  
  136.     handle->e_freq = ReadEClock(&eval);
  137.     handle->s_hi = eval.ev_hi;
  138.     handle->s_lo = eval.ev_lo;
  139.     handle->e_freq /= 20;
  140. }
  141.  
  142. GLboolean TMA_Check(LockTimeHandle *handle)
  143. {
  144.     struct EClockVal eval;
  145.     ULONG ticks;
  146.  
  147.     ReadEClock(&eval);
  148.  
  149.     if (eval.ev_hi == handle->s_hi)
  150.     {
  151.         ticks = eval.ev_lo - handle->s_lo;
  152.     }
  153.     else
  154.     {
  155.         ticks = (~0)-handle->s_lo + eval.ev_lo;
  156.     }
  157.  
  158.     if (ticks > handle->e_freq) return GL_TRUE;
  159.     else return GL_FALSE;
  160. }
  161.  
  162. #else
  163. void TMA_Start(LockTimeHandle *handle)
  164. {
  165.     GetSysTimePPC(&(handle->StartTime));
  166. }
  167.  
  168. GLboolean TMA_Check(LockTimeHandle *handle)
  169. {
  170.     struct timeval curTime;
  171.  
  172.     GetSysTimePPC(&curTime);
  173.     SubTimePPC(&curTime, &(handle->StartTime));
  174.     if (curTime.tv_secs) return GL_TRUE;
  175.     if (curTime.tv_micro > 50000) return GL_TRUE;
  176.     return GL_FALSE;
  177. }
  178. #endif
  179.  
  180.  
  181.  
  182. void GLBegin(GLcontext context, GLenum mode)
  183. {
  184. //    GLFlagError(context, context->CurrentPrimitive != GL_BASE, GL_INVALID_OPERATION);
  185.  
  186.     context->CurrentTexQValid = GL_FALSE; //Surgeon
  187.     context->VertexBufferPointer = 0;
  188.  
  189.     switch((int)mode)
  190.     {
  191.         case GL_POINTS:
  192.             //LOG(1, glBegin, "GL_POINTS");
  193.             context->CurrentPrimitive = mode;
  194.             context->CurrentDraw = (DrawFn)d_DrawPoints;
  195.             break;
  196.         case GL_LINES:
  197.             //LOG(1, glBegin, "GL_LINES");
  198.             context->CurrentPrimitive = mode;
  199.             context->CurrentDraw = (DrawFn)d_DrawLines;
  200.             break;
  201.         case GL_LINE_STRIP:
  202.             //LOG(1, glBegin, "GL_LINE_STRIP");
  203.             context->CurrentPrimitive = mode;
  204.             context->CurrentDraw = (DrawFn)d_DrawLineStrip;
  205.             break;
  206.         case GL_LINE_LOOP:
  207.             //LOG(1, glBegin, "GL_LINE_LOOP");
  208.             context->CurrentPrimitive = mode;
  209.             context->CurrentDraw = (DrawFn)d_DrawLineStrip;
  210.             break;
  211.         case GL_TRIANGLES:
  212.             //LOG(1, glBegin, "GL_TRIANLES");
  213.             context->CurrentPrimitive = mode;
  214.             //Surgeon:
  215.             //Delay setting pointer until we know the number of triangles that enters the pipeline
  216.             break;
  217.         case GL_TRIANGLE_STRIP:
  218.             //LOG(1, glBegin, "GL_TRIANGLE_STRIP");
  219.             context->CurrentPrimitive = mode;
  220.             context->CurrentDraw = (DrawFn)d_DrawTriangleStrip;
  221.             break;
  222.         case GL_TRIANGLE_FAN:
  223.             //LOG(1, glBegin, "GL_TRIANGLE_FAN");
  224.             context->CurrentPrimitive = mode;
  225.             context->CurrentDraw = (DrawFn)d_DrawTriangleFan;
  226.             break;
  227.         case GL_QUADS:
  228.             //LOG(1, glBegin, "GL_QUADS");
  229.             context->CurrentPrimitive = mode;
  230.             context->CurrentDraw = (DrawFn)d_DrawQuads;
  231.             break;
  232.         case GL_QUAD_STRIP:
  233.             //LOG(1, glBegin, "GL_QUAD_STRIP");
  234.             context->CurrentPrimitive = mode;
  235.             context->CurrentDraw = (DrawFn)d_DrawQuadStrip;
  236.             break;
  237.         case GL_POLYGON:
  238.             //LOG(1, glBegin, "GL_POLYGON");
  239.             context->CurrentPrimitive = mode;
  240.             if(context->Texture2D_State[1] == GL_TRUE)
  241.             context->CurrentDraw = (DrawFn)d_DrawMtexPoly;
  242.             else if(context->ShadeModel == GL_SMOOTH)
  243.             context->CurrentDraw = (DrawFn)d_DrawSmoothPoly;
  244.             else
  245.             context->CurrentDraw = (DrawFn)d_DrawNormalPoly;
  246.  
  247.             break;
  248.         case MGL_FLATFAN:
  249.             //LOG(1, glBegin, "MGL_FLATFAN");
  250.             context->CurrentPrimitive = mode;
  251.             context->CurrentDraw = (DrawFn)d_DrawFlat;
  252.             break;
  253.         case MGL_FLATSTRIP:
  254.             //LOG(1, glBegin, "MGL_FLATSTRIP");
  255.             context->CurrentPrimitive = mode;
  256.             context->CurrentDraw = (DrawFn)d_DrawFlat;
  257.             break;
  258.         default:
  259.             //LOG(1, glBegin, "Error GL_INVALID_OPERATION");
  260.             GLFlagError (context, 1, GL_INVALID_OPERATION);
  261.             break;
  262.     }
  263.  
  264.     //warp Current Normal
  265.  
  266.     if(context->NormalBufferPointer)
  267.     {
  268.         context->NormalBuffer[0].x = context->NormalBuffer[context->NormalBufferPointer].x;
  269.         context->NormalBuffer[0].y = context->NormalBuffer[context->NormalBufferPointer].y;
  270.         context->NormalBuffer[0].z = context->NormalBuffer[context->NormalBufferPointer].z;
  271.  
  272.     context->NormalBufferPointer = 0;
  273.     }
  274. }
  275.  
  276. //surgeon:
  277.  
  278. void GLPointSize(GLcontext context, GLfloat size)
  279. {
  280.     context->CurrentPointSize = size;
  281. }
  282.  
  283. #if !defined (__STORM__)
  284. static
  285. #endif
  286. inline W3D_Float CLAMPF(GLfloat x)
  287. {
  288.     if (x>=0.f && x<=1.f) return x;
  289.     else if (x<=0.f)      return 0.f;
  290.     else                  return 1.f;
  291. }
  292.  
  293.  
  294.  
  295. void GLColor4f(GLcontext context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
  296. {
  297.     //LOG(2, glColor4f, "%f %f %f %f", red, green, blue, alpha);
  298.  
  299. #ifdef CLAMP_COLORS
  300.     W3D_Float r,g,b,a;
  301.  
  302.     if (red<0.f)        r = 0.f;
  303.     else if (red>1.f)    r = 1.f;
  304.     else            r = red;
  305.  
  306.     if (green<0.f)        g = 0.f;
  307.     else if (green>1.f)    g = 1.f;
  308.     else            g = green;
  309.  
  310.     if (blue<0.f)        b = 0.f;
  311.     else if (blue>1.f)    b = 1.f;
  312.     else            b = blue;
  313.  
  314.     if (alpha<0.f)        a = 0.f;
  315.     else if (alpha>1.f)    a = 1.f;
  316.     else            a = alpha;
  317.  
  318.     context->CurrentColor.r = r;
  319.     context->CurrentColor.g = g;
  320.     context->CurrentColor.b = b;
  321.     context->CurrentColor.a = a;
  322. #else
  323.     context->CurrentColor.r = (W3D_Float)red;
  324.     context->CurrentColor.g = (W3D_Float)green;
  325.     context->CurrentColor.b = (W3D_Float)blue;
  326.     context->CurrentColor.a = (W3D_Float)alpha;
  327. #endif
  328.  
  329.     context->UpdateCurrentColor = GL_TRUE;
  330. }
  331.  
  332. void GLColor3f(GLcontext context, GLfloat red, GLfloat green, GLfloat blue)
  333. {
  334. #ifdef CLAMP_COLORS
  335.     W3D_Float r,g,b;
  336.  
  337.     if (red<0.f)        r = 0.f;
  338.     else if (red>1.f)    r = 1.f;
  339.     else            r = red;
  340.  
  341.     if (green<0.f)        g = 0.f;
  342.     else if (green>1.f)    g = 1.f;
  343.     else            g = green;
  344.  
  345.     if (blue<0.f)        b = 0.f;
  346.     else if (blue>1.f)    b = 1.f;
  347.     else            b = blue;
  348.  
  349.     context->CurrentColor.r = r;
  350.     context->CurrentColor.g = g;
  351.     context->CurrentColor.b = b;
  352.     context->CurrentColor.a = 1.f;
  353. #else
  354.     context->CurrentColor.r = (W3D_Float)red;
  355.     context->CurrentColor.g = (W3D_Float)green;
  356.     context->CurrentColor.b = (W3D_Float)blue;
  357.     context->CurrentColor.a = (W3D_Float)1.f;
  358. #endif
  359.  
  360.     context->UpdateCurrentColor = GL_TRUE;
  361. }
  362.  
  363. void GLColor4fv(GLcontext context, GLfloat *v)
  364. {
  365.     //LOG(2, glColor4fv, "%f %f %f %f", v[0], v[1], v[2], v[3]);
  366.  
  367.     W3D_Float red    = v[0];
  368.     W3D_Float green    = v[1];
  369.     W3D_Float blue    = v[2];
  370.     W3D_Float alpha    = v[3];
  371.  
  372. #ifdef CLAMP_COLORS
  373.     if (red<0.f)        red = 0.f;
  374.     else if (red>1.f)    red = 1.f;
  375.     if (green<0.f)        green = 0.f;
  376.     else if (green>1.f)    green = 1.f;
  377.     if (blue<0.f)        blue = 0.f;
  378.     else if (blue>1.f)    blue = 1.f;
  379.     if (alpha<0.f)        alpha = 0.f;
  380.     else if (alpha>1.f)    alpha = 1.f;
  381. #endif
  382.  
  383.     context->CurrentColor.r = red;
  384.     context->CurrentColor.g = green;
  385.     context->CurrentColor.b = blue;
  386.     context->CurrentColor.a = alpha;
  387.  
  388.     context->UpdateCurrentColor = GL_TRUE;
  389. }
  390.  
  391. void GLColor3fv(GLcontext context, GLfloat *v)
  392. {
  393.     //LOG(2, glColor3fv, "%f %f %f", v[0], v[1], v[2]);
  394.  
  395.     W3D_Float red    = v[0];
  396.     W3D_Float green    = v[1];
  397.     W3D_Float blue    = v[2];
  398.  
  399. #ifdef CLAMP_COLORS
  400.     if (red<0.f)        red = 0.f;
  401.     else if (red>1.f)    red = 1.f;
  402.     if (green<0.f)        green = 0.f;
  403.     else if (green>1.f)    green = 1.f;
  404.     if (blue<0.f)        blue = 0.f;
  405.     else if (blue>1.f)    blue = 1.f;
  406. #endif
  407.  
  408.     context->CurrentColor.r = red;
  409.     context->CurrentColor.g = green;
  410.     context->CurrentColor.b = blue;
  411.     context->CurrentColor.a = 1.0;
  412.  
  413.     context->UpdateCurrentColor = GL_TRUE;
  414. }
  415.  
  416. void GLColor4ub(GLcontext context, GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)
  417. {
  418.     register W3D_Float f = 1/255.0;
  419.     //LOG(2, glColor4ub, "%f %f %f %f", red*f, green*f, blue*f, alpha*f);
  420.  
  421.     // no clamping: ubyte always between 0 and 255 :)
  422.  
  423.     context->CurrentColor.r = (W3D_Float)red*f;
  424.     context->CurrentColor.g = (W3D_Float)green*f;
  425.     context->CurrentColor.b = (W3D_Float)blue*f;
  426.     context->CurrentColor.a = (W3D_Float)alpha*f;
  427.  
  428.     context->UpdateCurrentColor = GL_TRUE;
  429. }
  430.  
  431. void GLColor3ub(GLcontext context, GLubyte red, GLubyte green, GLubyte blue)
  432. {
  433.     register W3D_Float f = 1/255.0;
  434.  
  435.     // no clamping: ubyte always between 0 and 255 :)
  436.  
  437.     context->CurrentColor.r = (W3D_Float)red*f;
  438.     context->CurrentColor.g = (W3D_Float)green*f;
  439.     context->CurrentColor.b = (W3D_Float)blue*f;
  440.     context->CurrentColor.a = 1.f;
  441.  
  442.     context->UpdateCurrentColor = GL_TRUE;
  443. }
  444.  
  445. void GLColor4ubv(GLcontext context, GLubyte *v)
  446. {
  447.     register W3D_Float f = 1/255.0;
  448.  
  449.     //LOG(2, glColor4ubv, "%f %f %f %f", v[0]*f, v[1]*f, v[2]*f, v[3]*f);
  450.  
  451.     context->CurrentColor.r = (W3D_Float)v[0]*f;
  452.     context->CurrentColor.g = (W3D_Float)v[1]*f;
  453.     context->CurrentColor.b = (W3D_Float)v[2]*f;
  454.     context->CurrentColor.a = (W3D_Float)v[3]*f;
  455.  
  456.     context->UpdateCurrentColor = GL_TRUE;
  457. }
  458.  
  459. void GLColor3ubv(GLcontext context, GLubyte *v)
  460. {
  461.     register W3D_Float f = 1/255.0;
  462.     //LOG(2, glColor3ubv, "%f %f %f", v[0]*f, v[1]*f, v[2]*f);
  463.  
  464.     // no clamping: ubyte always between 0 and 255 :)
  465.  
  466.     context->CurrentColor.r = (W3D_Float)v[0]*f;
  467.     context->CurrentColor.g = (W3D_Float)v[1]*f;
  468.     context->CurrentColor.b = (W3D_Float)v[2]*f;
  469.     context->CurrentColor.a = (W3D_Float)1.0;
  470.  
  471.     context->UpdateCurrentColor = GL_TRUE;
  472. }
  473.  
  474. void GLNormal3f(GLcontext context, GLfloat x, GLfloat y, GLfloat z)
  475. {
  476.     //LOG(2, glNormal3f, "%f %f %f", x,y,z);
  477.  
  478.   GLuint nbp = ++context->NormalBufferPointer;
  479.   context->NormalBuffer[nbp].x = x;
  480.   context->NormalBuffer[nbp].y = y;
  481.   context->NormalBuffer[nbp].z = z;
  482. }
  483.  
  484. void GLNormal3fv(GLcontext context, GLfloat *n)
  485. {
  486. }
  487.  
  488.  
  489. #define CURRENTVERT context->VertexBuffer[context->VertexBufferPointer]
  490.  
  491. void GLMultiTexCoord2fARB(GLcontext context, GLenum unit, GLfloat s, GLfloat t)
  492. {
  493.     int u = unit - GL_TEXTURE0_ARB;
  494.  
  495.     if(u<0 || u>MAX_TEXUNIT)
  496.     return;
  497.  
  498.     if(u)
  499.     {
  500.         CURRENTVERT.tcoord.s = s;
  501.         CURRENTVERT.tcoord.t = t;
  502.     }
  503.     else //unit 0
  504.     {
  505.         CURRENTVERT.v.u = s;
  506.         CURRENTVERT.v.v = t;
  507.     }
  508. }
  509.  
  510. void GLMultiTexCoord2fvARB(GLcontext context, GLenum unit, GLfloat *v)
  511. {
  512.     int u = unit - GL_TEXTURE0_ARB;
  513.  
  514.     if(u<0 || u>MAX_TEXUNIT)
  515.     return;
  516.  
  517.     if(u)
  518.     {
  519.         CURRENTVERT.tcoord.s = v[0];
  520.         CURRENTVERT.tcoord.t = v[1];
  521.     }
  522.     else //unit 0
  523.     {
  524.         CURRENTVERT.v.u = v[0];
  525.         CURRENTVERT.v.v = v[1];
  526.     }
  527. }
  528.  
  529. void GLTexCoord2f(GLcontext context, GLfloat s, GLfloat t)
  530. {
  531.     //LOG(2, glTexCoord2f, "%f %f", s,t);
  532.  
  533.     #define thisvertex context->VertexBuffer[context->VertexBufferPointer]
  534.  
  535.     thisvertex.v.u = (W3D_Float)s;
  536.     thisvertex.v.v = (W3D_Float)t;
  537.     
  538.     #undef thisvertex
  539. }
  540.  
  541. void GLTexCoord2fv(GLcontext context, GLfloat *v)
  542. {
  543.     #define thisvertex context->VertexBuffer[context->VertexBufferPointer]
  544.  
  545.     thisvertex.v.u = (W3D_Float)v[0];
  546.     thisvertex.v.v = (W3D_Float)v[1];
  547.  
  548.     #undef thisvertex
  549.  
  550.     //LOG(2, glTexCoord2fv, "%f %f", v[0], v[1]);
  551. }
  552.  
  553. void GLTexCoord4f(GLcontext context, GLfloat s, GLfloat t, GLfloat r, GLfloat q)
  554. {
  555.     #define thisvertex context->VertexBuffer[context->VertexBufferPointer]
  556.  
  557.     thisvertex.v.u = (W3D_Float)s/(W3D_Float)q;
  558.     thisvertex.v.v = (W3D_Float)t/(W3D_Float)q;
  559.     thisvertex.q = q;
  560.  
  561.     context->CurrentTexQValid = GL_TRUE;
  562.  
  563.     #undef thisvertex
  564. }
  565.  
  566. void GLTexCoord4fv(GLcontext context, GLfloat *v)
  567. {
  568.     #define thisvertex context->VertexBuffer[context->VertexBufferPointer]
  569.  
  570.     thisvertex.v.u = (W3D_Float)v[1]/(W3D_Float)v[3];
  571.     thisvertex.v.v = (W3D_Float)v[2]/(W3D_Float)v[3];
  572.     thisvertex.q = v[3];
  573.  
  574.     context->CurrentTexQValid = GL_TRUE;
  575.  
  576.     #undef thisvertex
  577. }
  578.  
  579.  
  580. void GLVertex4f(GLcontext context, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
  581. {
  582.     #define thisvertex context->VertexBuffer[context->VertexBufferPointer]
  583.  
  584.     //LOG(1, glVertex4f, "%f %f %f %f", x,y,z,w);
  585.  
  586.     if(context->ShadeModel == GL_SMOOTH)
  587.     {
  588.     thisvertex.v.color.r = context->CurrentColor.r;
  589.     thisvertex.v.color.g = context->CurrentColor.g;
  590.     thisvertex.v.color.b = context->CurrentColor.b;
  591.     thisvertex.v.color.a = context->CurrentColor.a;
  592.     }
  593.  
  594.     thisvertex.bx = x;
  595.     thisvertex.by = y;
  596.     thisvertex.bz = z;
  597.     thisvertex.bw = w;
  598.  
  599.     thisvertex.normal = context->NormalBufferPointer;
  600.  
  601.     context->VertexBufferPointer ++;
  602.     #undef thisvertex
  603. }
  604.  
  605. void GLVertex4fv(GLcontext context, GLfloat *v)
  606. {
  607.     #define thisvertex context->VertexBuffer[context->VertexBufferPointer]
  608.  
  609.     if(context->ShadeModel == GL_SMOOTH)
  610.     {
  611.     thisvertex.v.color.r = context->CurrentColor.r;
  612.     thisvertex.v.color.g = context->CurrentColor.g;
  613.     thisvertex.v.color.b = context->CurrentColor.b;
  614.     thisvertex.v.color.a = context->CurrentColor.a;
  615.     }
  616.  
  617.     thisvertex.bx = v[0];
  618.     thisvertex.by = v[1];
  619.     thisvertex.bz = v[2];
  620.     thisvertex.bw = v[3];
  621.  
  622.     thisvertex.normal = context->NormalBufferPointer;
  623.  
  624.     context->VertexBufferPointer ++;
  625.     #undef thisvertex
  626. }
  627.  
  628. void GLVertex3fv(GLcontext context, GLfloat *v)
  629. {
  630.     #define thisvertex context->VertexBuffer[context->VertexBufferPointer]
  631.  
  632.     if(context->ShadeModel == GL_SMOOTH)
  633.     {
  634.     thisvertex.v.color.r = context->CurrentColor.r;
  635.     thisvertex.v.color.g = context->CurrentColor.g;
  636.     thisvertex.v.color.b = context->CurrentColor.b;
  637.     thisvertex.v.color.a = context->CurrentColor.a;
  638.     }
  639.  
  640.     thisvertex.bx = v[0];
  641.     thisvertex.by = v[1];
  642.     thisvertex.bz = v[2];
  643.     thisvertex.bw = 1.f;
  644.  
  645.     thisvertex.normal = context->NormalBufferPointer;
  646.  
  647.     context->VertexBufferPointer ++;
  648.     #undef thisvertex
  649. }
  650.  
  651. void GLVertex2f(GLcontext context, GLfloat x, GLfloat y)
  652. {
  653.     #define thisvertex context->VertexBuffer[context->VertexBufferPointer]
  654.  
  655.     //LOG(1, glVertex4f, "%f %f %f %f", x,y,z,w);
  656.  
  657.     if(context->ShadeModel == GL_SMOOTH)
  658.     {
  659.     thisvertex.v.color.r = context->CurrentColor.r;
  660.     thisvertex.v.color.g = context->CurrentColor.g;
  661.     thisvertex.v.color.b = context->CurrentColor.b;
  662.     thisvertex.v.color.a = context->CurrentColor.a;
  663.     }
  664.  
  665.     thisvertex.bx = x;
  666.     thisvertex.by = y;
  667.     thisvertex.bz = 0.0;
  668.     thisvertex.bw = 1.0;
  669.  
  670.     thisvertex.normal = context->NormalBufferPointer;
  671.  
  672.     context->VertexBufferPointer ++;
  673.     #undef thisvertex
  674. }
  675.  
  676. void GLVertex2fv(GLcontext context, GLfloat *v)
  677. {
  678.     #define thisvertex context->VertexBuffer[context->VertexBufferPointer]
  679.  
  680.     if(context->ShadeModel == GL_SMOOTH)
  681.     {
  682.     thisvertex.v.color.r = context->CurrentColor.r;
  683.     thisvertex.v.color.g = context->CurrentColor.g;
  684.     thisvertex.v.color.b = context->CurrentColor.b;
  685.     thisvertex.v.color.a = context->CurrentColor.a;
  686.     }
  687.  
  688.     thisvertex.bx = v[0];
  689.     thisvertex.by = v[1];
  690.     thisvertex.bz = 0.f;
  691.     thisvertex.bw = 1.f;
  692.  
  693.     thisvertex.normal = context->NormalBufferPointer;
  694.  
  695.     context->VertexBufferPointer ++;
  696.     #undef thisvertex
  697. }
  698.  
  699.  
  700. void GLDepthRange(GLcontext context, GLclampd n, GLclampd f)
  701. {
  702.     //LOG(2, glDepthRange, "%f %f", n, f);
  703.     context->near = n;
  704.     context->far  = f;
  705. #if 0
  706.     context->sz = (f-n)*0.5;
  707.     context->az = (n+f)*0.5;
  708. #else
  709.     context->sz = (GLfloat)((f-n)*0.5);
  710.     context->az = (GLfloat)((n+f)*0.5);
  711. #endif
  712. }
  713.  
  714.  
  715. void GLViewport(GLcontext context, GLint x, GLint y, GLsizei w, GLsizei h)
  716. {
  717.     GLuint clipflags;
  718.     //LOG(2, glViewPort, "%d %d %d %d", x,y,w,h);
  719.  
  720. //surgeon begin -->
  721.     //the are the default 'must' clipflags:
  722.  
  723.     if(context->GuardBand == GL_TRUE)
  724.     {
  725.         clipflags = (MGL_CLIP_NEGW|MGL_CLIP_BACK|MGL_CLIP_FRONT);
  726.  
  727.     //the following flags are viewport-dependant:
  728.  
  729.     if(x > 0)
  730.         clipflags |= MGL_CLIP_LEFT;
  731.  
  732.     if((x+w) < context->w3dScreen->Width)
  733.         clipflags |= MGL_CLIP_RIGHT;
  734.  
  735.     if(y > 0)
  736.         clipflags |= MGL_CLIP_BOTTOM;
  737.  
  738.     if((y+h) < context->w3dScreen->Height)
  739.         clipflags |= MGL_CLIP_TOP;
  740.  
  741.     context->ClipFlags = clipflags;
  742.     }
  743.     else //guardband clipping disabled
  744.     {
  745.     context->ClipFlags = (MGL_CLIP_NEGW | MGL_CLIP_BACK | MGL_CLIP_FRONT | MGL_CLIP_LEFT | MGL_CLIP_RIGHT | MGL_CLIP_TOP | MGL_CLIP_BOTTOM);
  746.     }
  747.  
  748. //surgeon end <--
  749.  
  750. #if 0 //double precision not needed
  751.  
  752.     context->ax = (double)x + (double)w*0.5;
  753.     context->ay =  (double)(context->w3dWindow->Height-context->w3dWindow->BorderTop-context->w3dWindow->BorderBottom)
  754.                   -(double)y - (double)h*0.5;
  755.     context->sx = (double)w * 0.5;
  756.     context->sy = (double)h * 0.5;
  757.  
  758. #else
  759.  
  760.     context->ax = (float)x + (float)w*0.5;
  761.     context->ay =  (float)(context->w3dWindow->Height-context->w3dWindow->BorderTop-context->w3dWindow->BorderBottom)
  762.                   -(float)y - (float)h*0.5;
  763.     context->sx = (float)w * 0.5;
  764.     context->sy = (float)h * 0.5;
  765.  
  766. #endif
  767. }
  768.  
  769.  
  770. extern void GLDrawElements(GLcontext context, GLenum mode, const GLsizei count, GLenum type, const GLvoid *indices);
  771.  
  772. //added 31-03-02: (moved from vertexelements.c)
  773.  
  774. void GLArrayElement(GLcontext context, GLint i)
  775. {
  776.     context->ElementIndex[context->VertexBufferPointer++] = (UWORD)i;
  777. }
  778.  
  779.  
  780. void GLEnd(GLcontext context)
  781. {
  782.     //LOG(1, glEnd, "");
  783.  
  784.     if(context->VertexBufferPointer == 0)
  785.     {
  786.         context->CurrentPrimitive = GL_BASE;
  787.         return; //no verts recorded
  788.     }
  789.  
  790.     if(context->ClientState & GLCS_VERTEX)
  791.     {
  792.         //assume that a series of glArrayElement commands has been issued
  793.         GLDrawElements(context, context->CurrentPrimitive, context->VertexBufferPointer, GL_UNSIGNED_SHORT, context->ElementIndex);
  794.  
  795.         context->CurrentPrimitive = GL_BASE;
  796.         return;
  797.     }
  798.  
  799.     if(context->Texture2D_State[1] == GL_TRUE)
  800.     {
  801.     //buffered drawing, so don't check for anything
  802.  
  803.         context->CurrentDraw(context);
  804.         context->CurrentPrimitive = GL_BASE;
  805.         return;
  806.     }
  807.  
  808.     if (context->FogDirty && context->Fog_State)
  809.     {
  810.         fog_Set(context);
  811.         context->FogDirty = GL_FALSE;
  812.     }
  813.  
  814.     if (context->ShadeModel == GL_FLAT)
  815.     {
  816.         if(context->UpdateCurrentColor == GL_TRUE)
  817.         {
  818.  
  819.         W3D_SetCurrentColor(context->w3dContext, &context->CurrentColor);
  820.         context->UpdateCurrentColor = GL_FALSE;
  821.         }
  822.     }
  823.  
  824.     // Check for blending inconsistancy
  825.     if (context->AlphaFellBack && (context->SrcAlpha == GL_ONE || context->DstAlpha == GL_ONE)
  826.         && context->Blend_State == GL_TRUE)
  827.     {
  828.         tex_ConvertTexture(context);
  829.     }
  830.  
  831.  
  832. /* Surgeon:
  833. ** if more than 20 triangles enters pipeline we use
  834. ** vertexarrays. I suppose 20 tris warrants the overhead
  835. ** of pointer modifications.
  836. */
  837.     if(context->CurrentPrimitive == GL_TRIANGLES)
  838.     {
  839.       if(context->VertexBufferPointer < 60)
  840.         context->CurrentDraw = (DrawFn)d_DrawTriangles;
  841.       else
  842.         context->CurrentDraw = (DrawFn)d_DrawTrianglesVA;
  843.     }
  844.  
  845.  
  846. #ifdef AUTOMATIC_LOCKING_ENABLE
  847.  
  848.     if (context->LockMode == MGL_LOCK_AUTOMATIC) // Automatic: Lock per primitive
  849.     {
  850.         if (W3D_SUCCESS == W3D_LockHardware(context->w3dContext))
  851.         {
  852.             context->w3dLocked = GL_TRUE;
  853.             context->CurrentDraw(context);
  854.             W3D_UnLockHardware(context->w3dContext);
  855.             context->w3dLocked = GL_FALSE;
  856.         }
  857.         else
  858.         {
  859.             printf("Error during LockHardware\n");
  860.         }
  861.     }
  862.     else if (context->LockMode == MGL_LOCK_MANUAL) // Manual: Lock manually
  863.     {
  864.         context->CurrentDraw(context);
  865.     }
  866.     else // Smart: Lock timer based
  867.     {
  868.         if (context->w3dLocked == GL_FALSE)
  869.         {
  870.             if (W3D_SUCCESS != W3D_LockHardware(context->w3dContext))
  871.             {
  872.                 printf("[glEnd] Error during W3D_LockHardware()\n");
  873.                 return; // give up
  874.             }
  875.             context->w3dLocked = GL_TRUE;
  876.             TMA_Start(&(context->LockTime));
  877.         }
  878.         context->CurrentDraw(context);  // Draw!
  879.         if (TMA_Check(&(context->LockTime)) == GL_TRUE)
  880.         {
  881.             // Time to unlock
  882.             W3D_UnLockHardware(context->w3dContext);
  883.             context->w3dLocked = GL_FALSE;
  884.         }
  885.     }
  886.  
  887. #else
  888.     context->CurrentDraw(context);
  889. #endif
  890.  
  891.     context->CurrentPrimitive = GL_BASE;
  892. }
  893.  
  894. void GLFinish(GLcontext context)
  895. {
  896.     //LOG(2, glFinish, "");
  897.     GLFlush(context);
  898.     W3D_WaitIdle(context->w3dContext);
  899. }
  900.  
  901. void GLFlush(GLcontext context)
  902. {
  903.     //LOG(2, glFlush, "");
  904. }
  905.  
  906.